Dynamic Strategy

서로 다른 포맷마다 서로 다른 전략을 공식화할 수 있고,
각각의 전략은 일반화되어 불변하는 상위 수준 텍스트 출력 알고리즘에 입력되어
세부 동작에 가변성을 부여

전략 디자인 패턴은 런타임에 변경 가능한 동적 형태와 템플릿으로 컴파일 타임에 결정되는 정적 형태가 있다.
동적 전략
enum class OutputFormat{
markdown, html
};
struct ListStrategy{
virtual void start(ostringstream& oss) {}
virtual void add_list_item(ostringstream& oss, const string& item) {}
virtual void end(ostringstream& oss) {}
};
//
struct TextProcessor{
void append_list(const vector<string> items){
list_strategy->start(oss);
for(auto& item: items) list_strategy->add_list_item(oss, item);
list_strtegy->end(oss);
}
private:
ostringstream oss;
unique_ptr<ListStrategy> list_strategy;
};
struct HtmlListStrategy: ListStrategy{
void start(ostringstream& oss) override {
oss<<"<ul>\n";
}
void end(ostringstream& oss) override {
oss<<"</ul>\n";
}
void add_list_item(ostringstream& oss, const string& item) override {
oss<<"<li>"<<item<<"</li>\n";
}
};
struct MarkdownListStrategy: ListStrategy{
void add_list_item(ostringstream& oss, const string& item) override {
oss<<" * "<<item<<endl;
}
};
void TextProcessor::set_output_format(const OutputFormat format){
switch(format){
case OutputFormat::markdown:
list_strategy=make_unique<MarkdownListStrategy>();
break;
case OutputFormat::html:
list_strategy=make_unique<HtmlListStrategy>();
break;
}
}
//
TextProcessor tp;
tp.set_output_format(OutputFormat::markdown);
tp.append_list({"foo", "bar", "baz"});
cout<<tp.str()<<endl;
tp.clear();
tp.set_output_format(OutputFormat::Html);
tp.append_list({"foo", "bar", "baz"});
cout<<tp.str()<<endl;
// <ul>
// <li> foo </li>
// <li> bar </li>
// <li> baz </li>
// </ul>